package org.txazo.blog.commons.parser;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.txazo.blog.util.ConstantsUtil;

/**
 * 解析器模板
 * 
 * @author Tu XiaoZhou
 * @since 2013-10-22
 * 
 */
public abstract class AbstractParser implements Parser {

	/** 输入文件 */
	private String input = null;
	/** 输出文件 */
	private String output = null;

	private boolean isFirstLineFlag = true;

	protected BufferedReader reader = null;
	protected BufferedWriter writer = null;

	private Matcher matcher = null;

	private static Pattern blankPattern = Pattern.compile("^\\s*$");
	private static Pattern headBlankPattern = Pattern.compile("^(\\s+).+");

	public AbstractParser(String input, String output) {
		this.input = input;
		this.output = output;
	}

	@Override
	public final void parse() {
		try {
			reader = new BufferedReader(new InputStreamReader(
					new FileInputStream(input),
					ConstantsUtil.CHARACTER_ENCODING_UTF_8));
			writer = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream(output),
					ConstantsUtil.CHARACTER_ENCODING_UTF_8));

			String className = this.getClass().getName();
			String type = className.substring(className.lastIndexOf(".") + 1,
					className.lastIndexOf("Parser")).toLowerCase();

			writer.write("<html lang=\"zh\">");
			writer.newLine();
			writer.write("<head>");
			writer.newLine();
			writer.write("<meta charset=\"utf-8\" />");
			writer.newLine();
			writer.write("<title>Shell</title>");
			writer.newLine();
			writer.write("<link type=\"text/css\" rel=\"stylesheet\" href=\"css/code.css\" />");
			writer.newLine();
			writer.write("</head>");
			writer.newLine();
			writer.write("<body>");
			writer.newLine();
			writer.write("<div id=\"nav\">");
			writer.newLine();
			writer.write("<div class=\"nav-list\">");
			writer.newLine();

			writer.write("<pre class=\"nav-" + type + "\">");
			writer.newLine();
			writer.write("<span class=\"" + type + "-pln\">");

			/** 逐行解析 */
			String line = null;
			while ((line = reader.readLine()) != null) {
				if (isFirstLineFlag) {
					isFirstLineFlag = false;
				} else {
					writer.newLine();
				}

				/** 排除空行 */
				if (!blankPattern.matcher(line).find()) {
					matcher = headBlankPattern.matcher(line);
					if (matcher.find()) {
						writer.write(matcher.group(1));
					}
					parse(line.trim());
				}
			}

			writer.write("</span>");
			writer.newLine();
			writer.write("</pre>");

			writer.newLine();
			writer.write("</div>");
			writer.newLine();
			writer.write("</div>");
			writer.newLine();
			writer.write("</body>");
			writer.newLine();
			writer.write("</html>");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (writer != null) {
				try {
					writer.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	protected abstract void parse(String line) throws IOException;

}
